package com.cans.core.service.impl;


import com.cans.core.dao.api.IBaseDao;
import com.cans.core.model.BaseModel;
import com.cans.core.service.api.IBaseService;
import org.hibernate.SessionFactory;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.List;

/**
 * 基类Service实现
 * @param <T>
 * @param <ID>
 */
public abstract class BaseServiceImpl<T extends BaseModel, ID extends Serializable> implements IBaseService<T,ID> {

    public BaseServiceImpl() {
        Type genType = getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        persistentClass =  (Class)params[0];
    }

    private Class<T> persistentClass;

    @Resource
    private SessionFactory sessionFactory;

    @Resource
    @PersistenceContext
    private EntityManager em;

    @Override
    public void saveOrUpdate(T t) {
        if (t == null){
            throw new RuntimeException("操作对象不可为空");
        }
        if(null != t.getId() && !t.getId().trim().equals("")){
            // 设置创建时间
            t.setCreateTime(new Date());
        }
        if(null == t.getId() && t.getId().trim().equals("")){
            // 设置最后修改时间
            t.setLastChangeTime(new Date());
        }
        getDaoImpl().save(t);
    }

    /**
     * 分页查询
     * @param page
     * @return
     */
    public Page<T> findPage(Pageable page){
        Page<T> userPage = getDaoImpl().findAll(page);
        return userPage;
    }

    /**
     * 删除
     * @param t
     */
    public void delete(T t){
        getDaoImpl().delete(t);
    }

    /**
     * 通过ID获取User
     * @param id
     * @return
     */
    public T findOne(ID id){
        T t = getDaoImpl().findOne(id);
        return t;
    }

    /**
     * 删除
     * @param id
     */
    public void delete(ID id){
        getDaoImpl().delete(id);
    }

    /**
     * 通过实例查询一批对象
     * @param t
     * @return
     */
    public List<T> findAll(T t){

        //创建匹配器，即如何使用查询条件
        ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
                .withMatcher("userName", ExampleMatcher.GenericPropertyMatchers.startsWith()) //姓名采用“开始匹配”的方式查询
                .withIgnorePaths("focus");  //忽略属性：是否关注。因为是基本类型，需要忽略掉

        Example<T> ex = Example.of(t, matcher);

        List<T> all = getDaoImpl().findAll(ex);


        return all;
    }

    /**
     * 查询全部
     * @return
     */
    public List<T> findAll(){
        return getDaoImpl().findAll();
    }

    public T findOne(T t){
        //创建匹配器，即如何使用查询条件
        ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
                .withMatcher("userName", ExampleMatcher.GenericPropertyMatchers.startsWith()) //姓名采用“开始匹配”的方式查询
                .withIgnorePaths("focus");  //忽略属性：是否关注。因为是基本类型，需要忽略掉

        Example<T> ex = Example.of(t, matcher);

        T one = getDaoImpl().findOne(ex);

        return one;
    }

    public abstract IBaseDao<T,ID> getDaoImpl();

}
